package com.zzg.datastructure.sort;

import java.util.Arrays;

/**
 * @Author zhengzg
 * @Date 2022-08-22
 * @Version v1.0
 * 插入排序
 */
public class InsertSort {
    public static void main(String[] args) {
        int[] arr = new int[]{-1,9,1,0,-2,5};
        insertSort(arr);
    }

    /**
     * 插入算法
     * 1. 把n个待排序的元素看成一个有序表和无序表，开始时有序表中只包含一个元素
     * 2. 无序表中包含n-1个元素，排序过程中每次从无序表中取出第一个元素，把它排序码
     * 依次与有序表元素的排序码进行比较，将它插入到有序表中的适当位置，使之成为新的有序表
     * @param arr 数组
     */
    private static void insertSort(int[] arr){
        // 无序表中插入有序表的数据
        int insertVal = 0;
        // 有序表中数据的索引，初始为第一个
        int insertIndex = 0;

        // 开始时将第一个元素作为有序表的第一个元素
        // 将无序表中第一个元素之后的数据作为插入有序表中的数据
        for (int i = 1; i < arr.length; i++) {
            insertVal = arr[i];
            insertIndex = i - 1;

            /*
             * 给insertVal找到插入的位置
             * 1. insertIndex >= 0保证插入位置不越界
             * 2. insertVal < arr[insertIndex] 待插入的数，还没找到插入位置
             * 2.1 insertVal 是无序表中的数据，arr[insertIndex]是有序表中最大的数据，-1是有序表值从后向前找
             * 2.2 insertVal < arr[insertIndex]表明要插入的数据，没有有序表中的数据大，
             * 所以将有序表数据后移，直到有序列表的索引无法再减小
             */
            while (insertIndex >= 0 && insertVal < arr[insertIndex]){
                arr[insertIndex + 1] = arr[insertIndex];
                insertIndex--;
            }

            /*
             * 1. 如果不需要赋值，即while循环没有执行,insertIndex = i - 1 与 insertIndex + 1作比较就能知道有无执行
             * 说明有序表最大的值小于当前要插入的值，抽象理解为直接插入到有序表最后
             * 2. 如果执行，举例说明：
             * 2.1 [34,101,99...]，insertVal此时是99，那么经过while，将变为[34,101,101...]，因为有序表数据后移
             * 2.2 此时insertIndex为0，arr[insertIndex + 1] = insertVal，执行之后->[34,99,101...]
             */
            if (insertIndex + 1 != i){
                arr[insertIndex + 1] = insertVal;
            }

            System.out.println("第"+i+"轮插入");
            System.out.println(Arrays.toString(arr));
        }


    }
}
